syntax = "proto3";

package kuma.mesh.v1alpha1;

option go_package = "github.com/kumahq/kuma/api/mesh/v1alpha1";

import "kuma-doc/config.proto";
import "api/mesh/options.proto";
import "api/mesh/v1alpha1/selector.proto";
import "api/system/v1alpha1/datasource.proto";
import "validate/validate.proto";

option (doc.config) = {
  type : Policy,
  name : "MeshGateway",
  file_name : "meshgateway"
};

// MeshGateway is a virtual proxy.
//
// Each MeshGateway is bound to a set of builtin gateway dataplanes.
// Each builtin dataplane instance can host exactly one Gateway
// proxy configuration.
//
// Gateway aligns with the Kubernetes Gateway API. See that
// spec for detailed documentation.
message MeshGateway {

  option (kuma.mesh.resource).name = "MeshGatewayResource";
  option (kuma.mesh.resource).type = "MeshGateway";
  option (kuma.mesh.resource).package = "mesh";

  option (kuma.mesh.resource).kds.send_to_zone = true;
  option (kuma.mesh.resource).ws.name = "meshgateway";

  // TLSConfig describes a TLS configuration.
  message TLS {
    enum Mode {
      // NONE is not a valid TLS mode. Ether TERMINATE or PASSTHROUGH must
      // be explicitly configured.
      NONE = 0;
      // The TLS session between the downstream client and the MeshGateway
      // is terminated at the MeshGateway. This mode requires the certificate
      // field to be set.
      TERMINATE = 1;
      // The TLS session is NOT terminated by the MeshGateway. This implies
      // that the MeshGateway can't decipher the TLS stream except for the
      // ClientHello message of the TLS protocol. The certificate field
      // is ignored in this mode.
      PASSTHROUGH = 2;
    }

    message Options {
      // TODO(jpeach)
    }

    // Aligns with MeshGatewayTLSConfig.
    message Conf {
      // Mode defines the TLS behavior for the TLS session initiated
      // by the client.
      Mode mode = 1;

      // Certificates is an array of datasources that contain TLS
      // certificates and private keys.  Each datasource must contain a
      // sequence of PEM-encoded objects. The server certificate and private
      // key are required, but additional certificates are allowed and will
      // be added to the certificate chain.  The server certificate must
      // be the first certificate in the datasource.
      //
      // When multiple certificate datasources are configured, they must have
      // different key types. In practice, this means that one datasource
      // should contain an RSA key and certificate, and the other an
      // ECDSA key and certificate.
      repeated kuma.system.v1alpha1.DataSource certificates = 2
          [ (validate.rules).repeated = {min_items : 1, max_items : 2} ];

      // Options should eventually configure how TLS is configured. This
      // is where cipher suite and version configuration can be specified,
      // client certificates enforced, and so on.
      Options options = 3;
    }
  }

  message Listener {
    message Resources { uint32 connection_limit = 1; }

    enum Protocol {
      NONE = 0;
      TCP = 1;
      TLS = 3;
      HTTP = 4;
      HTTPS = 5;
      // UDP = 2;
    }

    // Hostname specifies the virtual hostname to match for protocol types that
    // define this concept. When unspecified, "", or `*`, all hostnames are
    // matched. This field can be omitted for protocols that don't require
    // hostname based matching.
    string hostname = 1;

    // Port is the network port. Multiple listeners may use the
    // same port, subject to the Listener compatibility rules.
    uint32 port = 2;

    // Protocol specifies the network protocol this listener expects to receive.
    Protocol protocol = 3;

    // TLS is the TLS configuration for the Listener. This field
    // is required if the Protocol field is "HTTPS" or "TLS" and
    // ignored otherwise.
    TLS.Conf tls = 4;

    // Tags specifies a unique combination of tags that routes can use
    // to match themselves to this listener.
    //
    // When matching routes to listeners, the control plane constructs a
    // set of matching tags for each listener by forming the union of the
    // gateway tags and the listener tags. A route will be attached to the
    // listener if all of the route's tags are preset in the matching tags
    map<string, string> tags = 5;

    // CrossMesh enables traffic to flow to this listener only from other
    // meshes.
    bool crossMesh = 6;

    // Resources is used to specify listener-specific resource settings.
    Resources resources = 7;
  }

  // Conf defines the desired state of MeshGateway.
  //
  // Aligns with MeshGatewaySpec.
  message Conf {
    // Listeners define logical endpoints that are bound on this MeshGateway's
    // address(es).
    repeated Listener listeners = 2
        [ (validate.rules).repeated = {min_items : 1} ];

    // Note that the Kubernetes API Gateway resource defines a  list of
    // gateway addresses here. In Kuma, however, the Dataplane resources
    // owns the IP address(es) that it listens on, and those  addresses
    // will ultimately be where the Gateway is reachable.
  }

  // Selectors is a list of selectors that are used to match builtin
  // gateway dataplanes that will receive this MeshGateway configuration.
  repeated Selector selectors = 1
      [ (validate.rules).repeated = {min_items : 1} ];

  // Tags is the set of tags common to all of the gateway's listeners.
  //
  // This field must not include a `kuma.io/service` tag (the service is always
  // defined on the dataplanes).
  map<string, string> tags = 2 [ (validate.rules).repeated = {min_items : 1} ];

  // The desired configuration of the MeshGateway.
  Conf conf = 3;
}
